<template>
  <div :class="{c_table:!isCancel}">
    <!-- 功能区 -->
    <div class="c_headbut">
      <slot name="top">
        <template v-for="(item, index) in butHeadConf">
          <el-button :key="index" :type="item.type" :size="item.size" :style="item|topButCss_f"
            :disabled="!(item.status==null?true:item.status)"
            :icon="item.icon" @click="buttonEvent(1, item)">{{ item.name }}</el-button>
        </template>
      </slot>
      <!-- 额外最加 -->
      <slot name="topAppend"></slot>
      <!-- 搜索 -->
      <slot name="search">
        <el-input size="mini" class="c_search" :style="searchConf.style" v-if="searchConf&&searchConf.open" v-model="search" clearable
          :placeholder="searchConf.placeholder" @keyup.enter.native="buttonEvent(2, searchConf)">
          <template #prepend><slot name="search_prepend"></slot></template>
          <i slot="prefix" class="el-input__icon el-icon-search"></i>
          <el-button slot="append" @click="buttonEvent(2, searchConf)">{{ searchConf.btnTxt }}</el-button>
        </el-input>
      </slot>
      <!-- 搜索后-额外追加 -->
      <slot name="topEnd"></slot>
    </div>
    <el-table ref="table" :data="tableData" :page="!!pageConf"
      v-bind="tConf" v-on="tableEven"
      @selection-change="handle(3,arguments[0])"
      @sort-change="handle(0,arguments[0])"
      @current-change="handle(2,arguments[0])">>
      <!-- 是否多选-批量操作 sortable -->
      <el-table-column type="selection" align="center" v-if="selectionOption.open" :selectable="selectionOption.valid"></el-table-column>
      <!-- 简单模式 -->
      <template v-if="headData">
        <el-table-column v-for="(value, key, index) in headData" :label="value" :prop="key" :key="index" align="center"
          :sortable="sortForm(key)" :sort-method="sortForm(key, true)" show-overflow-tooltip>
          <!-- 列内容-自定义 -->
          <template #default="{row, column, $index}">
            <slot :name="key" :row="row" :column="column" :$index="$index">
              <slot :row="row" :column="column" :$index="$index">{{ row[key] }}</slot>
            </slot>
          </template>
          <!-- 列-表头-自定义 -->
          <template #header="{column, $index}">
            <slot :name="key+'_header'" :column="column" :$index="$index">
              <slot name="header" :column="column" :$index="$index">{{ value }}</slot>
            </slot>
          </template>
        </el-table-column>
      </template>
      <!-- 复杂模式 -->
      <template v-else-if="headList">
        <template v-for="(item, index) in headList">
          <el-table-column :key="index" :type="item.type"
            :label="item.label" :prop="item.prop" :width="item.width" :min-width="item.minWidth"
            :fixed="item.fixed" :sortable="item.sortable" :sort-method="item.sortMethod"
            :show-overflow-tooltip="item.hide" :align="item.align||'center'" :resizable="item.resizable"
            :column-key="item.columnKey" :class-name="item.className" :selectable="item.selectable">
              <!-- 列内容-自定义 -->
              <template #default="{row, column, $index}" v-if="item.type!='selection'">
                <slot :name="item.prop" :row="row" :column="column" :$index="$index">
                  <slot :row="row" :column="column" :$index="$index">{{ row|defVal_f(item, $index, pageConf) }}</slot>
                </slot>
              </template>
              <!-- 列-表头-自定义 -->
              <template #header="{column, $index}">
                <slot :name="item.prop+'_header'" :column="column" :$index="$index">
                  <slot name="header" :column="column" :$index="$index">{{ item.label }}</slot>
                </slot>
              </template>
          </el-table-column>
        </template>
      </template>
      <!-- 更多操作 -->
      <el-table-column v-if="tableMore && tableMore.length" label="操作" align="center">
        <template #default="{row, $index}">
            <el-button v-for="(item, ind) in tableMore" :key="ind" :type="item.type" size="mini"
              :icon="item.icon" @click="tableMoreEvent({row, index:$index}, {row:item, index: ind})">{{ item.name }}</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 -->
    <slot name="tablePage">
      <c-page v-if="pageConf&&pageConf.open" @pageChange="handle(1,arguments[0])"
      :offset.sync="pageConf.offset" :limit.sync="pageConf.limit" :isEndTxt="pageConf.pageEnd||pConf.pageEnd"
      :total="pageConf.total" :curPage.sync="pageConf.curPage" :small="pageConf.small||pConf.small"
      :pageCount="pageConf.pageCount" :layout="pageConf.layout||pConf.layout" :addLayout="pageConf.addLayout"
      :pageSizes="pageConf.pageSizes" :isHide="pageConf.isHide||pConf.isHide" :bgBtn="pageConf.bgBtn||pConf.bgBtn">
        <template v-if="pageConf.otherHandle" #start>
          <i class="c_icon el-icon-search" title="高级搜索" @click="pageConf.otherHandle('search')"
            v-if="pageConf.show==null||pageConf.show==1" />
          <i class="c_icon el-icon-refresh" title="刷新" @click="pageConf.otherHandle('refresh')"
            v-if="pageConf.show==null||pageConf.show==2" />
        </template>
      </c-page>
    </slot>
  </div>
</template>
<script>
import { Table, TableColumn, Button, Input } from 'element-ui'
import cPage from './cPage' // 分页组件
// import { butDataDef, searchDataDef, pageConfDef } from './config/table' // 导入table全局-相关配置
import * as tableDef from './config/table' // 导入table全局-相关配置
export default {
  name: 'jzTable',
  props: {
    tableData: { // table数据
      type: Array,
      default() {
        return []
      }
    },
    tableConf: { // table 配置
      type: Object,
      default() { return {} }
    },
    tableEven: Object, // table-事件
    tableMore: Array, // 更多操作-按钮,
    headData: Object, // 表头数据-简单模式
    headList: Array, // 表头-配置模式
    border: Boolean, // table边框是否需要
    butData: [Boolean, Array], // 列表-功能区-合并
    butList: Array, // 列表-功能区-全新
    selection: { // 是否开启多选 open | valid
      type: [Boolean, Object]
    },
    sortData: Array, // 排序配置 key valid
    searchData: { // 搜索-数据配置
      type: [Boolean, Object]
    },
    showSummary: Boolean, // 合计
    pageConf: Object, // 分页配置
    isCancel: Boolean // 取消-自定义布局
  },
  data() {
    return {
      // 搜索值
      search: ''
    }
  },
  computed: {
    // 选中参数-配置
    selectionOption() {
      const valid = function(row, index) {
        return true
      }
      if (this.selection) {
        if (typeof this.selection == 'boolean') {
          return { open: this.selection, valid }
        } else {
          return this.selection
        }
      } else {
        return { open: false, valid }
      }
    },
    // 功能区-按钮
    butHeadConf() {
      const butDef = JSON.parse(JSON.stringify(tableDef.butDataDef)) // 脱离绑定-避免影响其他
      if (this.butList) { // 全新功能区-不合并
        this.butList.forEach(o => {
          const defObj = butDef.find(e => e.id == o.id)
          if (defObj) {
            Object.keys(defObj).filter(k => !o.hasOwnProperty(k)).forEach(k => {
              o[k] = defObj[k]
            })
          }
        })
        return this.butList.filter(o => o.show || o.show == null)
      }
      return []
    },
    // 搜索
    searchConf() {
      const searchDef = JSON.parse(JSON.stringify(tableDef.searchDataDef)) // 脱离绑定-避免影响其他
      if (this.searchData != null) {
        if (typeof this.searchData == 'boolean') { // boolean 类型
          if (!this.searchData) { // 关闭
            searchDef[0].open = this.searchData
            return searchDef[0]
          }
        } else {
          const o = this.searchData
          const defObj = searchDef.find(e => e.id == o.id)
          if (defObj) {
            Object.keys(defObj).filter(k => !o.hasOwnProperty(k)).forEach(k => {
              o[k] = defObj[k]
            })
          }
          return o
        }
      }
      return null
    },
    // 分页-功能选择
    pConf() {
      if (this.pageConf) {
        return JSON.parse(JSON.stringify(tableDef.pageConfDef))
      }
      return null
    },
    // table-默认数据-配置
    tConf() {
      // 脱离绑定-避免影响其他
      const searchDef = JSON.parse(JSON.stringify(tableDef.tableConfDef))
      const conf = this.$commUtil.copyObj(this.tableConf, searchDef)
      if (conf.currRow != null) {
        conf['highlight-current-row'] = conf.currRow
        delete conf.currRow
      }
      if (this.border != null) {
        conf['border'] = this.border
      }
      return conf
    }
  },
  components: {
    ElTable: Table, ElTableColumn: TableColumn,
    ElButton: Button, ElInput: Input, cPage
  },
  created() {
  },
  updated() {
    this.$nextTick(_ => {
      this.$refs['table'].doLayout()
    })
  },
  methods: {
    // 更多操作
    tableMoreEvent(table, button) {
      this.$emit('tableMoreEvent', { table, button })
    },
    // 按钮功能区-回调事件 1 按钮 2 搜索框
    buttonEvent(type, row) {
      switch (type) {
        case 1: // 按钮
          if (row.callback) {
            row.callback(row)
          } else {
            this.$emit('buttonEvent', row)
          }
          break
        case 2: { // 搜索框
          const data = { id: row.id, value: this.search }
          if (row.callback) {
            row.callback(data)
          } else {
            this.$emit('buttonEvent', data)
          }
          break
        }
      }
    },
    // 回调-特殊处理
    handle(type, row) {
      // 排序 分页  当前选中  多选
      const arr = ['sortChange', 'pageChange', 'currentChange', 'selectionChange']
      const fnStr = arr[type]
      if (fnStr && this.tableConf[fnStr]) {
        this.tableConf[fnStr](row)
      } else {
        this.$emit(fnStr, row)
      }
    },
    // 多选是-设置默认值 type 1单 2多
    setSelection(type, row, status) {
      switch (type) {
        case 1: { // 单选
          this.$refs.table.setCurrentRow(row)
          break
        }
        case 2: { // 多选
          if (row) {
            this.$refs.table.toggleRowSelection(row, status)
          } else {
            this.$refs.table.clearSelection()
          }
          break
        }
      }
    },
    // 排序处理 bool 验证
    sortForm(key, bool) {
      if (this.sortData) {
        const obj = this.sortData.find(o => o.key == key)
        if (bool) {
          return obj != null ? obj.valid : null
        } else {
          return obj != null ? obj.value : false
        }
      } else {
        if (!bool) {
          return false
        }
      }
    }
  },
  filters: {
    // 处理默认值
    defVal_f(row, item, rowInd, page) {
      switch (item.type) {
        case 'index': { // 默认-ind
          const start = page ? (page.curPage - 1) * page.limit : 0
          return rowInd + 1 + start
        }
        default:
          return row[item.prop]
      }
    },
    // 属性默认值
    arrtVal_f(row, val) {
      return row == null ? val : row
    },
    // top 按钮样式
    topButCss_f(row) {
      if (row.size) {
        return row.size === 'xs' ? 'padding: 5px 7px;' : row.style
      }
      return ''
    }
  }
}
</script>
<style lang="scss" scoped>
@import '~@/styles/mixin';
.c_headbut{ // 功能区
  &>button{
    margin-bottom: 10px;
  }
}
::v-deep .c_search{
  width: 280px;
  float: right;
  margin-bottom: 10px;
  input:nth-child(1){
    border-radius: 20px 0 0 20px;
  }
  .el-input-group__prepend{
    padding: 0 5px;
    border-radius: 20px 0 0 20px;
  }
  .el-input-group__append{
    border-radius: 0 20px 20px 0;
  }
}
// 列表-样式调整
.c_table{
  height: 100%;
  overflow: auto;
  @include scrollBar($h: 8px);
  ::v-deep{
    // 头部
    .el-table__header-wrapper,.el-table__fixed-header-wrapper{
      th{
        // color: #777;
        // background-color: #f0f0f0;
        color: #8090a0;
        background-color: #ecf2f7;
      }
    }
    // body - 滚动条
    .el-table__body-wrapper{
      @include scrollBar($h: 8px);
    }
    // table-外层
    .el-table{
      &[page]{margin: 0 0 36px;}
      border: 1px solid #EBEEF5;
    }
    .u_foot{
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100%;
      padding: 5px;
      // background: #f0f0f0;
      background-color: #ecf2f7;
      .page-txt[small]{float: right;}
      .page-el{
        &>button{background-color:#f0f0f0}
      }
    }
  }
  .c_icon{
    cursor: pointer;
    font-weight: bold;
    margin-right: 5px;
    vertical-align: middle;
    &.el-icon-search{color:#E6A23C;}
    &.el-icon-refresh{color:#67C23A;}
  }
}
</style>
